package com.meego.common.memcache.xmem;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import ops.ga.config.Config;
import ops.ga.log4j.GA;
import ops.ga.plugin.ObjectRepository;
import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.MemcachedClientBuilder;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.transcoders.Transcoder;
import org.apache.jasper.tagplugins.jstl.core.ForEach;

public class XManPool {

    private static final String prefix = "meego.xmem.";
    private static XManPool sInstance;
    private Map<String, MemcachedClient> mPool;

    public static synchronized XManPool getInstance() {
        if (sInstance == null) {
            sInstance = new XManPool();
        }

        return sInstance;
    }

    public XManPool() {
        mPool = new HashMap<String, MemcachedClient>();
        try {
            initPool();
        } catch (Exception e) {
            System.out.println("Shutdown Program!!!. Can't init XmenPool");
            GA.sysmessage.error("Shutdown Program!!! Can't init XmenPool", e);
            System.exit(1);
        }
    }

    private void initPool() throws Exception {
        StringTokenizer st = new StringTokenizer(Config.getStrConfig(prefix + "instance", "default"), ", \n\t");

        while (st.hasMoreTokens()) {
            String xmem = st.nextToken().trim().toLowerCase();
            int size = Config.getIntConfig(prefix + xmem + ".pool.size", 3);
            int timeout = Config.getIntConfig(prefix + xmem + ".timeout", 0);
            int port = Config.getIntConfig(prefix + xmem + ".port", 0);
            String host = Config.getStrConfig(prefix + xmem + ".ip", "localhost");
            List<InetSocketAddress> lstSocket = new ArrayList<InetSocketAddress>();
            InetSocketAddress s = new InetSocketAddress(host, port);
            for(int i = 0 ; i < size; i ++){
                lstSocket.add(s);
            }

            MemcachedClientBuilder mcb = new XMemcachedClientBuilder(lstSocket);
            mcb.setConnectionPoolSize(size);
            mcb.setConnectTimeout(timeout);
            MemcachedClient client = mcb.build();
            Object transcoder = ObjectRepository.getPlugin("transcoder", xmem);
            if (transcoder instanceof Transcoder) {
                Transcoder tcoder = (Transcoder) transcoder;
                mcb.setTranscoder(tcoder);
                GA.app.error("added " + xmem + " connection to XmenPool");
                mPool.put(xmem, client);
            } else {
                GA.app.error("None Transcoder for XmenPool: " + xmem);
            }
        }
    }

    public void shutdown() {
        synchronized (mPool) {
            Iterator<String> scan = mPool.keySet().iterator();
            while (scan.hasNext()) {
                String key = scan.next();
                MemcachedClient cl = mPool.get(key);
                try {
                    cl.shutdown();
                    scan.remove();
                    GA.app.error("shutdown memcache " + key + " SUCCESSFULLY");
                } catch (Exception e) {
                    GA.app.error("shutdown memcache " + key + " FAILURE", e);
                }
            }
            mPool.notifyAll();
        }
    }

    public MemcachedClient getClient(String key) {
        return mPool.get(key);
    }
}
